#include "dht11.h"

#define DHT11_HIGH GPIO_SetBits(GPIOA, GPIO_Pin_3)
#define DHT11_LOW GPIO_ResetBits(GPIOA, GPIO_Pin_3)
#define DHT11_READ GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_3)

void dht11Out()
{
	GPIO_InitTypeDef GPIO_InitStruct;
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStruct);
}

void dht11In()
{
	GPIO_InitTypeDef GPIO_InitStruct;
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3;
	GPIO_Init(GPIOA, &GPIO_InitStruct);
}

void dht11Reset()
{
	dht11Out();
	DHT11_LOW;
	myDelayMs(20);
	DHT11_HIGH;
	myDelayUs(30);
}

u8 dht11Check()
{
	u8 retry = 0;
	dht11In();
	while(DHT11_READ && retry < 100)
	{
		retry++;
		myDelayUs(1);
	}
	if(retry >= 100)
	{
		return 0;
	}
	else
	{
		retry = 0;
	}

	while(!DHT11_READ && retry < 100)
	{
		retry++;
		myDelayUs(1);
	}
	if(retry >= 100)
	{
		return 0;
	}
	return 1;
}

u8 dht11ReadBit()
{
	u8 retry = 0;
	while(DHT11_READ && retry < 100)
	{
		retry++;
		myDelayUs(1);
	}
	retry = 0;
	while(!DHT11_READ && retry < 100)
	{
		retry++;
		myDelayUs(1);
	}
	myDelayUs(40);
	if(DHT11_READ)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

u8 dht11ReadByte()
{
	u8 i,dat;
	dat = 0;
	for(i = 0; i < 8; i++)
	{
		dat <<= 1;
		dat |= dht11ReadBit();
	}
	return dat;
}

u8 dht11ReadData(u8 *temp,u8 *humi)
{
	u8 buf[5];
	u8 i;
	dht11Reset();
	if(dht11Check() == 1)
	{
		for(i = 0; i < 5; i++)
		{
			buf[i] = dht11ReadByte();
		}
		if(buf[0] + buf[1] + buf[2] + buf[3] == buf[4])
		{
			*humi = buf[0];
			*temp = buf[2];
		}
	}
	else
	{
		return 0;
	}
	return 1;
}

u8 dht11Init()
 { 
	GPIO_InitTypeDef GPIO_InitStructure; 
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); //使能PG端口时钟
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //PG11端口配置
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;  //推挽输出
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化IO口
	GPIO_SetBits(GPIOA,GPIO_Pin_3); //PG11 输出高 
	dht11Reset(); //复位DHT11
	return dht11Check();//等待DHT11的回应
 }